<template>
    <view v-if="showPopup" class="uni-popup" :class="[popupstyle]" @touchmove.stop.prevent="clear">
        <uni-transition v-if="maskShow" class="uni-mask--hook" :mode-class="['fade']" :styles="maskClass"
            :duration="duration" :show="showTrans" @click="onTap" />
        <uni-transition :mode-class="ani" :styles="transClass" :duration="duration" :show="showTrans" @click="onTap">
            <view class="uni-popup__wrapper-box" @click.stop="clear">
                <slot />
            </view>
        </uni-transition>
    </view>
</template>

<script>
    import uniTransition from '../uni-transition/uni-transition.vue'
    import popup from './popup.js'
    /**
     * PopUp 弹出层
     * @description 弹出层组件，为了解决遮罩弹层的问题
     * @tutorial https://ext.dcloud.net.cn/plugin?id=329
     * @property {String} type = [top|center|bottom] 弹出方式
     * 	@value top 顶部弹出
     * 	@value center 中间弹出
     * 	@value bottom 底部弹出
     * 	@value message 消息提示
     * 	@value dialog 对话框
     * 	@value share 底部分享示例
     * @property {Boolean} animation = [ture|false] 是否开启动画
     * @property {Boolean} maskClick = [ture|false] 蒙版点击是否关闭弹窗
     * @event {Function} change 打开关闭弹窗触发，e={show: false}
     */

    export default {
        name: 'UniPopup',
        components: {
            uniTransition
        },
        props: {
            // 开启动画
            animation: {
                type: Boolean,
                default: true
            },
            // 弹出层类型，可选值，top: 顶部弹出层；bottom：底部弹出层；center：全屏弹出层
            // message: 消息提示 ; dialog : 对话框
            type: {
                type: String,
                default: 'center'
            },
            // maskClick
            maskClick: {
                type: Boolean,
                default: true
            }
        },
        provide() {
            return {
                popup: this
            }
        },
        mixins: [popup],
        watch: {
            /**
             * 监听type类型
             */
            type: {
                handler: function (newVal) {
                    this[this.config[newVal]]()
                },
                immediate: true
            },
            /**
             * 监听遮罩是否可点击
             * @param {Object} val
             */
            maskClick(val) {
                this.mkclick = val
            }
        },
        data() {
            return {
                duration: 300,
                ani: [],
                showPopup: false,
                showTrans: false,
                maskClass: {
                    'position': 'fixed',
                    'bottom': 0,
                    'top': 0,
                    'left': 0,
                    'right': 0,
                    'backgroundColor': 'rgba(0, 0, 0, 0.4)'
                },
                transClass: {
                    'position': 'fixed',
                    'left': 0,
                    'right': 0,
                },
                maskShow: true,
                mkclick: true,
                popupstyle: 'top'
            }
        },
        created() {
            this.mkclick = this.maskClick
            if (this.animation) {
                this.duration = 300
            } else {
                this.duration = 0
            }
        },
        methods: {
            clear(e) {
                // TODO nvue 取消冒泡
                e.stopPropagation()
            },
            open() {
                this.showPopup = true
                this.$nextTick(() => {
                    new Promise(resolve => {
                        clearTimeout(this.timer)
                        this.timer = setTimeout(() => {
                            this.showTrans = true
                            // fixed by mehaotian 兼容 app 端
                            this.$nextTick(() => {
                                resolve();
                            })
                        }, 50);
                    }).then(res => {
                        // 自定义打开事件
                        clearTimeout(this.msgtimer)
                        this.msgtimer = setTimeout(() => {
                            this.customOpen && this.customOpen()
                        }, 100)
                        this.$emit('change', {
                            show: true,
                            type: this.type
                        })
                    })
                })
            },
            close(type) {
                this.showTrans = false
                this.$nextTick(() => {
                    this.$emit('change', {
                        show: false,
                        type: this.type
                    })
                    clearTimeout(this.timer)
                    // 自定义关闭事件
                    this.customOpen && this.customClose()
                    this.timer = setTimeout(() => {
                        this.showPopup = false
                    }, 300)
                })
            },
            onTap() {
                if (!this.mkclick) return
                this.close()
            },
            /**
             * 顶部弹出样式处理
             */
            top() {
                this.popupstyle = 'top'
                this.ani = ['slide-top']
                this.transClass = {
                    'position': 'fixed',
                    'left': 0,
                    'right': 0,
                }
            },
            /**
             * 底部弹出样式处理
             */
            bottom() {
                this.popupstyle = 'bottom'
                this.ani = ['slide-bottom']
                this.transClass = {
                    'position': 'fixed',
                    'left': 0,
                    'right': 0,
                    'bottom': 0
                }
            },
            /**
             * 中间弹出样式处理
             */
            center() {
                this.popupstyle = 'center'
                this.ani = ['zoom-out', 'fade']
                this.transClass = {
                    'position': 'fixed',
                    /* #ifndef APP-NVUE */
                    'display': 'flex',
                    'flexDirection': 'column',
                    /* #endif */
                    'bottom': 0,
                    'left': 0,
                    'right': 0,
                    'top': 0,
                    'justifyContent': 'center',
                    'alignItems': 'center'
                }
            }
        }
    }
</script>
<style scoped>
    .uni-popup {
        position: fixed;
        /* #ifndef APP-NVUE */
        z-index: 9999;
        /* #endif */
    }

    .uni-popup__mask {
        position: absolute;
        top: 0;
        bottom: 0;
        left: 0;
        right: 0;
        background-color: rgba(0, 0, 0, 0.4);
        opacity: 0;
    }

    .mask-ani {
        transition-property: opacity;
        transition-duration: 0.2s;
    }

    .uni-top-mask {
        opacity: 1;
    }

    .uni-bottom-mask {
        opacity: 1;
    }

    .uni-center-mask {
        opacity: 1;
    }

    .uni-popup__wrapper {
        /* #ifndef APP-NVUE */
        display: block;
        /* #endif */
        position: absolute;
    }

    .top {
        /* #ifdef H5 */
        top: var(--window-top);
        /* #endif */
        /* #ifndef H5 */
        top: 0;
        /* #endif */
    }

    .bottom {
        bottom: 0;
    }

    .uni-popup__wrapper-box {
        /* #ifndef APP-NVUE */
        display: block;
        /* #endif */
        position: relative;
        /* iphonex 等安全区设置，底部安全区适配 */
        /* #ifndef APP-NVUE */
        padding-bottom: constant(safe-area-inset-bottom);
        padding-bottom: env(safe-area-inset-bottom);
        /* #endif */
    }

    .content-ani {
        /* transition: transform 0.3s;
 */
        transition-property: transform, opacity;
        transition-duration: 0.2s;
    }


    .uni-top-content {
        transform: translateY(0);
    }

    .uni-bottom-content {
        transform: translateY(0);
    }

    .uni-center-content {
        transform: scale(1);
        opacity: 1;
    }
</style>